/**
 * Copyright (c) suzuki ryoutoku
 * See this code regarding the Apache License Version 2.0
 * @file Log.h
 */

//=============================================================================
//	pre processor
//=============================================================================
#include "Log.h"
#include <unistd.h>
#include <ctime>
#include <cstring>
using namespace library::log;

//=============================================================================
//	LogManager's class member
//=============================================================================
/**
 *
 * \note
 *
 *
 * @author suzuki ryoutoku 
 * @date 2008-1-3
 * @version 1.0
 */
LogManager LogManager::instance;

//=============================================================================
//	LogManager's method
//=============================================================================
/**
 * @author suzuki ryoutoku 
 * @date 2008-1-3
 * @version 1.0
 */
LogManager::LogManager()
{
  this->m_fp = NULL;
  memset(this->m_logfilename, 0, 256);
  memset(this->m_logdirname, 0, 256);
}

/**
 * @author suzuki ryoutoku 
 * @date 2008-1-3
 * @version 1.0
 */
LogManager::~LogManager()
{
}


/**
 *
 * @author suzuki ryoutoku 
 * @date 2008-1-3
 * @version 1.0
 */
void LogManager::initialize(const string& arg)
{
  string dirname = arg;
  size_t pos = dirname.rfind("/");

  // No specified directory.
  if( pos == string::npos ){
	// make a determination that user's home directory in the meantime.
	char currentdir[256];
	bool flag = true;
	getcwd(currentdir,256);
	strcpy(this->m_logdirname, currentdir);
	strcpy(this->m_logfilename, arg.c_str());
  }else{
	dirname.erase(pos, dirname.size()-1);
	
	strcpy(this->m_logdirname, dirname.c_str());
	for( int i = pos+1; i < arg.size(); i++ ){
	  this->m_logfilename[i] = arg[i];
	}
  }

  // Initialize log file
  char currentdir[256];
  
  getcwd(currentdir,256);
  chdir(this->m_logdirname);
  this->m_fp = fopen( this->m_logfilename, "w");
  fclose( this->m_fp );
  chdir(currentdir);
}

/**
 * This method allow you to write log file.
 * 
 * @param foramt 
 *
 * @author suzuki ryoutoku 
 * @date 2008-1-3
 * @version 1.0
 */
void LogManager::print(const char* format, ...)
{
  va_list args;
  int index_of_format = 0;
  char currentdir[256];
  
  getcwd(currentdir,256);
  chdir(this->m_logdirname);
  this->m_fp = fopen( this->m_logfilename, "a");
  if( this->m_fp == NULL ){
	return;
  } 
	 

  // parse argument
  va_start( args, format);
  while( format[index_of_format] != '\0'){
	if( format[index_of_format] != '%' || format[index_of_format+1] == '\0' ){
	  fputc( format[index_of_format], this->m_fp );
	  index_of_format++;
	}else{
	  if( format[index_of_format+1] == 's' ){
		char* s = va_arg( args, char* );
		fprintf( this->m_fp, "%s", s);
	  }else if( format[index_of_format+1] == 'd'){
		int d = va_arg( args, int );
		fprintf( this->m_fp, "%d", d);
	  }else if( format[index_of_format+1] == 'e'){
		double t = va_arg( args, double );
		fprintf( this->m_fp, "%e", t);
	  }else if( format[index_of_format+1] == 'f'){
		double t = va_arg( args, double );
		fprintf( this->m_fp, "%f", t);
	  }else{
		fputc( '%', this->m_fp );
		fputc( format[index_of_format+1], this->m_fp );
	  }
	  index_of_format += 2;
	}
  }
  va_end( args );
  
  fclose( this->m_fp );
  chdir(currentdir);
}

/**
 * This method create now time information, store it in argument.
 * @param arg it's size must be 23
 * @author suzuki ryoutoku 
 * @date 2008-1-6
 * @version 1.0
 */
char* LogManager::storeTime(char* arg)
{
  struct tm *ptime;
  time_t t;
  t = time((time_t*)0);
  ptime = localtime( &t );//convert local time
  sprintf(arg,
		  "%d-%d/%d %d:%d %d(sec)",
		  ptime->tm_year + 1900,
		  ptime->tm_mon + 1,
		  ptime->tm_mday,
		  ptime->tm_hour,
		  ptime->tm_min,
		  ptime->tm_sec);
  return arg;
}


/**
 *
 * @author suzuki ryoutoku 
 * @date 2008-1-3
 * @version 1.0
 */
LogManager* LogManager::GetInstance()
{
    return &instance;
}
